package com.whfp.coky.utils

import com.whfp.coky.ui.task.model.AutoBqBean
import com.whfp.coky.ui.task.model.SearchBQBean
import com.whfp.coky.ui.task.model.TestVoBean
import java.util.*

/**
 *
 * 上位机检测结果计算工具类
 * created by coky on 2022/3/30
 */
class CaculateBQUtil {

    companion object{
        //原始值数据源
        private var yszArray: MutableList<Int>? = null

        //标曲数据源
        private var listBasicBQ: List<AutoBqBean.ValueAllVOBean>? = null

        //标曲数据
        private var qzdbqBean: AutoBqBean? = null


        //start-重要判定值-start====================================================================================================
        //标曲类型
        private val bqType: Int? = null

        //最低浓度
        private var lowConcentration: Double? = null

        //C值起始值
        private var cValueStart: Int? = null

        //C值结束值
        private var cValueEnd: Int? = null

        //T1值起始值
        private var t1ValueStart: Int? = null

        //T1值结束值
        private var t1ValueEnd: Int? = null

        //T2值起始值
        private var t2ValueStart: Int? = null

        //T2值结束值
        private var t2ValueEnd: Int? = null

        //T3值起始值
        private var t3ValueStart: Int? = null

        //T3值结束值
        private var t3ValueEnd: Int? = null
        //end-重要判定值-end====================================================================================================


        //end-重要判定值-end====================================================================================================
        //start-原始值中获取的重要数值-start=====================================================================================
        //C值位置
        private var cPos: Int? = null

        //T1值位置
        private var t1Pos: Int? = null

        //T2位置
        private var t2Pos: Int? = null

        //T3位置
        private var t3Pos: Int? = null

        //C值
        private var cValue: Double? = null

        //T1值
        private var t1Value: Double? = null

        //T2值
        private var t2Value: Double? = null

        //T3值
        private var t3Value: Double? = null
        //end-原始值中获取的重要数值-end=========================================================================================


        //end-原始值中获取的重要数值-end=========================================================================================
        //start-计算出来的重要数值-start=====================================================================================
        //T1/C值
        private var t1_cValue: Double? = null

        //T2/C值
        private var t2_cValue: Double? = null

        //T3/C值
        private var t3_cValue: Double? = null

        //T1浓度值
        private var t1ConcentrationValue: Double? = null

        //T2浓度值
        private var t2ConcentrationValue: Double? = null

        //T3浓度值
        private var t3ConcentrationValue: Double? = null

        //用于装载计算好的T比C值和对应的浓度值
        private val listJCJG: ArrayList<TestVoBean> = ArrayList<TestVoBean>()
        //end-计算出来的重要数值-end=====================================================================================

        //end-计算出来的重要数值-end=====================================================================================
        /**
         * 清空所有数值
         */
        private fun toNull() {
            //最低浓度
            lowConcentration = null
            //C值起始值
            cValueStart = null
            //C值结束值
            cValueEnd = null
            //T1值起始值
            t1ValueStart = null
            //T1值结束值
            t1ValueEnd = null
            //T2值起始值
            t2ValueStart = null
            //T2值结束值
            t2ValueEnd = null
            //T3值起始值
            t3ValueStart = null
            //T3值结束值
            t3ValueEnd = null
            //C值位置
            cPos = -1
            //T1值位置
            t1Pos = -1
            //T2值位置
            t2Pos = -1
            //T3值位置
            t3Pos = -1
            //C值
            cValue = null
            //T1值
            t1Value = null
            //T2值
            t2Value = null
            //T3值
            t3Value = null
            //T1/C值
            t1_cValue = 0.00
            //T2/C值
            t2_cValue = 0.00
            //T3/C值
            t3_cValue = 0.00
            //T1浓度值
            t1ConcentrationValue = -666666.00
            //T2浓度值
            t2ConcentrationValue = -666666.00
            //T3浓度值
            t3ConcentrationValue = -666666.00
            //用于装载计算好的T比C值和对应的浓度值
            listJCJG.clear()
        }


        fun calculationResult(ysz: List<Int>?, searchBqBean: SearchBQBean): ArrayList<TestVoBean>? {
            //清空所有值
            toNull()
            /**
             * 处理原始值
             */
            yszArray = ysz as MutableList<Int>?
//        yszArray = ArrayList<Int>()
//        yszArray.addAll(ysz!!)
            /**
             * 处理标曲json串
             */
            if (searchBqBean.biaoQuType == 1) {
                qzdbqBean = searchBqBean.biaoQuFile as AutoBqBean
            }
            lowConcentration = qzdbqBean?.lowConcentration
//         LogUtil.e("最低浓度是：\$lowConcentration")
            //C值起始值
            cValueStart = qzdbqBean?.startC
//         LogUtil.e("C值起始值：\$cValueStart")
            //C值结束值
            cValueEnd = qzdbqBean?.endC
//         LogUtil.e("C值结束值：\$cValueEnd")
            //T1值起始值
            t1ValueStart = qzdbqBean?.startT1
            //T1值结束值
            t1ValueEnd = qzdbqBean?.endT1
            //T2值起始值
            t2ValueStart = qzdbqBean?.startT2
            //T2值结束值
            t2ValueEnd = qzdbqBean?.endT2
            //T3值起始值
            t3ValueStart = qzdbqBean?.startT3
            //T3值结束值
            t3ValueEnd = qzdbqBean?.endT3
            //标曲数据
            listBasicBQ = qzdbqBean?.varueAllVO
            listBasicBQ?.let {
                for (bq in it) {
                    LogUtil.e( "T1/C值：" + bq.t1CValue.toString() + ",T2/C值：" + bq.t2CValue
                        .toString() + ",T3/C值：" + bq.t3CValue
                        .toString() + "对应的浓度值：" + bq.concentration)
                }
            }

            /**
             * 开始计算浓度值
             */
            //获取C值
            if (cValueStart != null && cValueEnd != null) {
                if (yszArray!!.size >= cValueEnd!! && yszArray!!.size >= cValueStart!!) {
                    cValue =
                        getListPartIsMaxValue(yszArray!!, cValueStart!!.toInt(), cValueEnd!!.toInt(), 0)
                    LogUtil.e("C值是：$cValue")
                } else {
                    LogUtil.e("C线异常！")
                    return null
                }
            } else {
                LogUtil.e("C值起始值或结束值为空！")
                return null
            }
            //获取T1值
            if (t1ValueStart != null && t1ValueEnd != null && t1ValueStart != 0 && t1ValueEnd != 0) {
                t1Value =
                    getListPartIsMaxValue(yszArray!!, t2ValueStart!!.toInt(), t2ValueEnd!!.toInt(), 2)
                LogUtil.e("t2值是：$t2Value")
            } else {
                LogUtil.e("t2值起始值或结束值为空！")
            }
            //获取t3值
            if (t3ValueStart != null && t3ValueEnd != null && t3ValueStart != 0 && t3ValueEnd != 0) {
                t3Value =
                    getListPartIsMaxValue(yszArray!!, t3ValueStart!!.toInt(), t3ValueEnd!!.toInt(), 3)
                LogUtil.e("t3值是：$t3Value")
            } else {
                LogUtil.e("t3值起始值或结束值为空！")
            }
            //获取T比C值
            if (t1Value != null) {
                t1_cValue = t1Value!! / cValue!! //T1值比C的值
                LogUtil.e("T1比C的值是：$t1_cValue")
            }
            if (t2Value != null) {
                t2_cValue = t2Value!! / cValue!! //T2值比C的值
                LogUtil.e("T2比C的值是：$t2_cValue")
            }
            if (t3Value != null) {
                t3_cValue = t3Value!! / cValue!! //T3值比C的值
                LogUtil.e("T3比C的值是：$t3_cValue")
            }
            //开始获取浓度值
            t1ConcentrationValue = -666666.00
            t2ConcentrationValue = -666666.00
            t3ConcentrationValue = -666666.00
            for (i in listBasicBQ!!.indices) {
                val b: AutoBqBean.ValueAllVOBean = listBasicBQ!![i]
                var b2: AutoBqBean.ValueAllVOBean? = null
                //是否是标曲第一个
                var isFrist = false
                if (i - 1 >= 0) {
                    isFrist = false
                    b2 = listBasicBQ!![i - 1]
                } else {
                    isFrist = true
                    LogUtil.e("i-1=" + (i - 1))
                }
                //获取T1浓度值
                if (t1_cValue != 0.00 && t1_cValue!! >= b.t1CValue!! && t1ConcentrationValue == -666666.00) {
                    LogUtil.e("当前的i的下标是：" + i + "，当前标曲中T1比C的值是：" + b.t1CValue)
                    t1ConcentrationValue = if (t1_cValue === b.t1CValue) {
                        b.concentration
                    } else if (isFrist) {
                        0.01
                    } else {
                        calculateConcentrationValue(t1_cValue, 1, b, b2)
                    }
                    LogUtil.e("T1浓度值：$t1ConcentrationValue")
                }
                //获取T2浓度值
                if (t2_cValue != 0.00 && t2_cValue!! >= b.t2CValue!! && t2ConcentrationValue == -666666.00) {
                    t2ConcentrationValue = if (t2_cValue === b.t2CValue) {
                        b.concentration
                    } else if (isFrist) {
                        0.01
                    } else {
                        calculateConcentrationValue(t2_cValue, 2, b, b2)
                    }
                    LogUtil.e("T2浓度值：$t2ConcentrationValue")
                }
                //获取T3浓度值
                if (t3_cValue != 0.00 && t3_cValue!! >= b.t3CValue!! && t3ConcentrationValue == -666666.00) {
                    t3ConcentrationValue = if (t3_cValue === b.t3CValue!!) {
                        b.concentration
                    } else if (isFrist) {
                        0.01
                    } else {
                        calculateConcentrationValue(t3_cValue, 3, b, b2)
                    }
                    LogUtil.e("T3浓度值：$t3ConcentrationValue")
                }
            }
            //检测值冲顶的解决方案
            if (t1Value != null && t1ConcentrationValue == -666666.00) {
                t1ConcentrationValue = 999.00
            }
            if (t2Value != null && t2ConcentrationValue == -666666.00) {
                t2ConcentrationValue = 999.00
            }
            if (t3Value != null && t3ConcentrationValue == -666666.00) {
                t3ConcentrationValue = 999.00
            }
            //装载检测结果
            listJCJG.clear()
            if (t1ConcentrationValue != -666666.00) {
                listJCJG.add(
                    TestVoBean().apply {
                        this.drugsName = qzdbqBean?.nameT1
                        this.cValue = Companion.cValue.toString()
                        this.tValue = t1Value.toString()
                        this.potency = String.format("%.2f",t1ConcentrationValue)
                        this.result = ""
                        this.unit = "ng/mg"
                        this.cPos = cPos
                        this.tPos = t1Pos!!
                        this.ctValue = String.format("%.2f",t1_cValue)
                    }
                )
            }
            if (t2ConcentrationValue != -666666.00) {
                listJCJG.add(
                    TestVoBean().apply {
                        this. drugsName = qzdbqBean?.nameT2
                        this. cValue = Companion.cValue.toString()
                        this.tValue = t2Value.toString()
                        this.potency = String.format("%.2f",t2ConcentrationValue)
                        this. result = ""
                        this.unit = "ng/mg"
                        this.cPos = cPos
                        this.tPos = t2Pos!!
                        this.ctValue = String.format("%.2f",t2_cValue)
                    }
                )
            }
            if (t3ConcentrationValue != -666666.00) {
                listJCJG.add(

                    TestVoBean().apply {
                        this.drugsName = qzdbqBean?.nameT3
                        this.cValue = Companion.cValue.toString()
                        this.tValue = t3Value.toString()
                        this.potency = String.format("%.2f",t3ConcentrationValue)
                        this.result = ""
                        this.unit = "ng/mg"
                        this.cPos = cPos
                        this.tPos = t3Pos!!
                        this.ctValue = String.format("%.2f",t3_cValue)
                    }
                )
            }
            LogUtil.e("有多少个检测数据：" + listJCJG.size)
            return listJCJG
        }


        /**
         * 截取ArrayList<Int>中某一段数据，并获取此段数据中的最大值
         *
         * @param listData 原始数据
         * @param start    起始值
         * @param end      结束值
         * @param type     0:C值计算  1：T1值计算  2：T2值计算  3：T3值计算
         * @return 截取过后数据段中的最大值
        </Int> */
        private fun getListPartIsMaxValue(
            listData: List<Int>,
            start: Int,
            end: Int,
            type: Int
        ): Double? {
            return if (listData.isEmpty()) {
                LogUtil.e("原始数据为空！")
                null
            } else if (listData.size < start) {
                LogUtil.e("原始数据数量小于起始下标！")
                null
            } else if (listData.size < end) {
                LogUtil.e("原始数据数量小于结束下标！")
                null
            } else if (start > end) {
                LogUtil.e("起始值大于结束值！")
                null
            } else {
                //根据起始值和结束值截取原始数据段
                val cArray: List<Int> = yszArray!!.subList(start, end)
                //得到数据段中的最大值
                val max = Collections.max(cArray).toDouble()
                when (type) {
                    0 -> cPos = cArray.indexOf(max.toInt()) + start
                    1 -> t1Pos = cArray.indexOf(max.toInt()) + start
                    2 -> t2Pos = cArray.indexOf(max.toInt()) + start
                    3 -> t3Pos = cArray.indexOf(max.toInt()) + start
                }
                max
            }
        }

        /**
         * 计算浓度值
         *
         * @param t_cValue 计算出来的T比C值
         * @param b1       等于或刚好大于当前计算出来的T比C值的标曲对象
         * @param b2       b1对象的相邻的前一个标曲对象
         * @return 计算好的浓度值
         */
        private fun calculateConcentrationValue(
            t_cValue: Double?,
            type: Int,
            b1: AutoBqBean.ValueAllVOBean?,
            b2: AutoBqBean.ValueAllVOBean?
        ): Double {
            return if (b1 == null || b2 == null) {
                0.00
            } else {
                val b1concentration: Double? = b1.concentration
                val b1concentration_b2concentration: Double =
                    b1.concentration?.minus(b2.concentration!!)!!


                if (type == 1) { //计算T1对应结果值
                    val t_b1t1c: Double = Math.abs(t_cValue?.minus(b1.t1CValue!!)!!)
                    val b2t1c_b1t1c: Double = Math.abs(b2.t1CValue!! - b1.t1CValue!!)
                    //开始计算
                    b1concentration?.minus(t_b1t1c / b2t1c_b1t1c * b1concentration_b2concentration)!!
                } else if (type == 2) { //计算T2对应结果值
                    val t_b1t2c: Double = Math.abs(t_cValue?.minus(b1.t2CValue!!)!!)
                    val b2t2c_b1t2c: Double = Math.abs(b2.t2CValue?.minus(b1.t2CValue!!)!!)
                    //开始计算
                    b1concentration?.minus(t_b1t2c / b2t2c_b1t2c * b1concentration_b2concentration)!!
                } else { //计算T3对应结果值
                    val t_b1t3c: Double = Math.abs(t_cValue?.minus(b1.t3CValue!!)!!)
                    val b2t3c_b1t3c: Double = Math.abs(b2.t3CValue!! - b1.t3CValue!!)
                    //开始计算
                    b1concentration?.minus(t_b1t3c / b2t3c_b1t3c * b1concentration_b2concentration)!!
                }
            }
        }
    }
}
